package es.uji.viselab.sceneview;

import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

/**
 * This class stores a TransforGroup that manages one single joint
 * <p>
 * The TransformGroup was put here when the 3D robot was created. After that,
 * each time a joint should rotate, the TransformGroup changes accordingly and
 * affect the according objects of the scene
 * 
 * @author Roger Esteller-Curto
 * 
 */
public class VirtualRobotJoints {
	
	protected TransformGroup tg = new TransformGroup();
	protected Point3f origin;
	protected float rotX = 0;
	protected float rotY = 0;
	protected float rotZ = 0;

	public VirtualRobotJoints() {
		tg = new TransformGroup();
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		this.origin = new Point3f(0, 0, 0);
	}

	VirtualRobotJoints(TransformGroup tg, Point3f origin) {
		this.tg = tg;
		this.origin = origin;
	}

	VirtualRobotJoints(TransformGroup tg) {
		this.tg = tg;
		this.origin = new Point3f(0, 0, 0);
	}

	public TransformGroup getTg() {
		return tg;
	}

	public void setTg(TransformGroup tg) {
		this.tg = tg;
	}

	public Point3f getOrigin() {
		return origin;
	}

	public void setOrigin(Point3f origin) {
		this.origin = origin;
	}

	public void setOrigin(Point3d center) {
		this.origin = new Point3f((float) center.x, (float) center.y, (float) center.z);
	}

	/**
	 * Rotates the joint in degrees
	 * 
	 * @param d Long value in degrees
	 */
	public void setDegrees(double d) {

		Vector3f translationVectorA;
		Vector3f translationVectorB;
		Transform3D transformA;
		Transform3D transformB;
		Transform3D transformRotX;
		Transform3D transformRotY;
		Transform3D transformRotZ;

		translationVectorA = new Vector3f(-origin.x, -origin.y, -origin.z);
		translationVectorB = new Vector3f(origin.x, origin.y, origin.z);
		transformA = new Transform3D();
		transformB = new Transform3D();
		transformA.setTranslation(translationVectorA);
		transformB.setTranslation(translationVectorB);
		transformRotX = new Transform3D();
		transformRotY = new Transform3D();
		transformRotZ = new Transform3D();
		// only one of following (rotX, rotY, rotZ) will be "1", the other "0"
		// and you know what happens when multiply one number by "0" right ?
		transformRotX.rotX(rotX * (d / 360.0) * 2 * Math.PI);
		transformRotY.rotY(rotY * (d / 360.0) * 2 * Math.PI);
		transformRotZ.rotZ(rotZ * (d / 360.0) * 2 * Math.PI);
		transformA.mul(transformRotX, transformA);
		transformA.mul(transformRotY, transformA);
		transformA.mul(transformRotZ, transformA);
		transformA.mul(transformB, transformA);
		tg.setTransform(transformA);
	}

	public float getRotX() {
		return rotX;
	}

	public void setRotX(float rotX) {
		this.rotX = rotX;
	}

	public float getRotY() {
		return rotY;
	}

	public void setRotY(float rotY) {
		this.rotY = rotY;
	}

	public float getRotZ() {
		return rotZ;
	}

	public void setRotZ(float rotZ) {
		this.rotZ = rotZ;
	}

}
